package com.newlink.building.common_base.http

import android.util.Log
import com.newlink.building.common_base.BuildConfig
import com.newlink.building.common_base.api.Base_ApiService
import com.newlink.building.common_base.api.NL_ApiService
import com.newlink.building.common_base.base.BaseApplication
import com.newlink.building.common_base.constant.Base_Constant
import com.newlink.building.common_base.constant.Base_HttpConstant
import com.newlink.building.common_base.http.interceptor.Base_CacheInterceptor
import com.newlink.building.common_base.http.interceptor.Base_HeaderInterceptor
import com.newlink.building.common_base.http.interceptor.Base_SaveCookieInterceptor
import com.newlink.building.common_base.http.interceptor.Base_LoggingInterceptor
import okhttp3.Cache
import okhttp3.HttpUrl
import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
import okhttp3.Interceptor
import okhttp3.OkHttpClient
import okhttp3.Response
import okhttp3.logging.HttpLoggingInterceptor
import retrofit2.Retrofit
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory
import retrofit2.converter.gson.GsonConverterFactory
import java.io.File
import java.util.concurrent.TimeUnit


object Base_RetrofitHelper {

    private var retrofit: Retrofit? = null
    val service: Base_ApiService by lazy { getRetrofit()!!.create(Base_ApiService::class.java) }

    private var retrofit2: Retrofit? = null
    val xLinkService: NL_ApiService by lazy { getXLinkRetrofit()!!.create(NL_ApiService::class.java) }

    private val dynamicUrlInterceptor = DynamicUrlInterceptor(Base_Constant.BASE_URL.plus("/"))

    private fun getRetrofit(): Retrofit? {
        if (retrofit == null) {
            Log.e("RetrofitHelper", "baseUrl ${Base_Constant.BASE_URL.plus("/")}")
            retrofit = Retrofit.Builder()
                .baseUrl(Base_Constant.BASE_URL.plus("/"))  // baseUrl
                .client(getOkHttpClient())
                .addConverterFactory(GsonConverterFactory.create())
//                    .addConverterFactory(MoshiConverterFactory.create())
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .build()
        }
        return retrofit
    }

    private fun getXLinkRetrofit(): Retrofit? {
        if (retrofit2 == null) {
            Log.e("RetrofitHelper", "getXLinkRetrofit ${Base_Constant.BASE_XLINK_URL.plus("/")}")
            retrofit2 = Retrofit.Builder()
                .baseUrl(Base_Constant.BASE_XLINK_URL.plus("/"))  // baseUrl - 协议服务固定使用BASE_XLINK_URL
                .client(getXLinkOkHttpClient())
                .addConverterFactory(GsonConverterFactory.create())
//                    .addConverterFactory(MoshiConverterFactory.create())
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .build()
        }
        return retrofit2
    }

    //动态切换URL地址
    fun refreshDynamicBaseUrl() {
        Log.e("RetrofitHelper", "refreshDynamicBaseUrl ${Base_Constant.BASE_URL.plus("/")}")
        dynamicUrlInterceptor.setDynamicBaseUrl(Base_Constant.BASE_URL.plus("/"))
    }

    /**
     * 获取 OkHttpClient
     */
    private fun getOkHttpClient(): OkHttpClient {
        val builder = OkHttpClient().newBuilder()
        val httpLoggingInterceptor = HttpLoggingInterceptor()
        if (BuildConfig.DEBUG) {
            httpLoggingInterceptor.level = HttpLoggingInterceptor.Level.BODY
        } else {
            httpLoggingInterceptor.level = HttpLoggingInterceptor.Level.NONE
        }

        //设置 请求的缓存的大小跟位置
        val cacheFile = File(BaseApplication.context.cacheDir, "cache")
        val cache = Cache(cacheFile, Base_HttpConstant.MAX_CACHE_SIZE)

        builder.run {
            // 在DEBUG模式下使用增强日志拦截器，否则使用原有的日志拦截器
            if (BuildConfig.DEBUG) {
                addInterceptor(Base_LoggingInterceptor())
            } else {
                addInterceptor(httpLoggingInterceptor)
            }
            addInterceptor(Base_HeaderInterceptor())
            addInterceptor(Base_SaveCookieInterceptor())
            addInterceptor(Base_CacheInterceptor())
            addInterceptor(dynamicUrlInterceptor)
            cache(cache)  //添加缓存
            connectTimeout(Base_HttpConstant.DEFAULT_TIMEOUT, TimeUnit.SECONDS)
            readTimeout(Base_HttpConstant.DEFAULT_TIMEOUT, TimeUnit.SECONDS)
            writeTimeout(Base_HttpConstant.DEFAULT_TIMEOUT, TimeUnit.SECONDS)
            retryOnConnectionFailure(true) // 错误重连
//             cookieJar(FvlCookieJar())
        }
        return builder.build()
    }

    /**
     * 获取 OkHttpClient
     */
    private fun getXLinkOkHttpClient(): OkHttpClient {
        val builder = OkHttpClient().newBuilder()
        val httpLoggingInterceptor = HttpLoggingInterceptor()
        if (BuildConfig.DEBUG) {
            httpLoggingInterceptor.level = HttpLoggingInterceptor.Level.BODY
        } else {
            httpLoggingInterceptor.level = HttpLoggingInterceptor.Level.NONE
        }

        //设置 请求的缓存的大小跟位置
        val cacheFile = File(BaseApplication.context.cacheDir, "cache")
        val cache = Cache(cacheFile, Base_HttpConstant.MAX_CACHE_SIZE)

        builder.run {
            // 在DEBUG模式下使用增强日志拦截器，否则使用原有的日志拦截器
            if (BuildConfig.DEBUG) {
                addInterceptor(Base_LoggingInterceptor())
            } else {
                addInterceptor(httpLoggingInterceptor)
            }
            addInterceptor(Base_HeaderInterceptor())
            addInterceptor(Base_SaveCookieInterceptor())
            addInterceptor(Base_CacheInterceptor())
            cache(cache)  //添加缓存
            connectTimeout(Base_HttpConstant.DEFAULT_TIMEOUT, TimeUnit.SECONDS)
            readTimeout(Base_HttpConstant.DEFAULT_TIMEOUT, TimeUnit.SECONDS)
            writeTimeout(Base_HttpConstant.DEFAULT_TIMEOUT, TimeUnit.SECONDS)
            retryOnConnectionFailure(true) // 错误重连
//             cookieJar(FvlCookieJar())
        }
        return builder.build()
    }

    //带端口的URL拦截器
    class DynamicUrlInterceptor(url: String) : Interceptor {
        private var dynamicBaseUrl: HttpUrl? = null

        init {
            dynamicBaseUrl = url.toHttpUrlOrNull()
        }

        fun setDynamicBaseUrl(url: String) {
            dynamicBaseUrl = url.toHttpUrlOrNull()
        }

        override fun intercept(chain: Interceptor.Chain): Response {
            val originalRequest = chain.request()
            if (dynamicBaseUrl != null) {

            }
            val newUrl = originalRequest.url.newBuilder()
                .scheme(dynamicBaseUrl!!.scheme)
                .host(dynamicBaseUrl!!.host)
                .port(dynamicBaseUrl!!.port) // 添加端口号
                .build()

            val newRequest = originalRequest.newBuilder()
                .url(newUrl)
                .build()

            return chain.proceed(newRequest)
        }
    }
}